# encoding:utf8
''' 资源发布工具 '''
import os
import time
import sys
import logging
import json
import shutil
from optparse import OptionParser
from pylibs import LuaPackRes
from PackSheet import PackSheet

#=======================================
# default params
DB_FILENAME = "resmd5.db"

RELEASE_PLAT_CONFIG = dict(
    # android
    android=dict(
        respath="res",
        tarpath="res_etc1",
        platform="android"
    ),
    # ios
    ios=dict(
        respath="res",
        tarpath="res_pvr",
        platform="ios"
    )
)
#=======================================


def path_compatible(path):
    ''' 文件路径兼容 '''
    return path.replace("/", os.sep)


class ReleaseRes(object):
    ''' 工具 '''
    _texcfg = None  # 纹理打包的配置
    _chglist = None  # 文件改变的列表
    PLAT_SUFFIX = dict(
        default="png",
        android="etc1",
        ios="pvr"
    )

    @classmethod
    def _pack_img(cls, fileobj, filename):
        confkey = filename.split(os.sep)[-1].split(".")[0]
        if cls._texcfg.has_key(confkey):
            logging.info("Pack the texture confkey-->>%s", confkey)
            packtype = None
            # chk is bigger than 1024*1024
            # from PIL import Image
            # reson:Etc1 final size is double normal texture.So the normal texture size
            #      must under 1024 /
            #      PVR3 must POT and square and under 2048
            # img = Image.open(fileobj)
            # isbigger = (img.size[0] > 1024) or (img.size[1] > 1024)
            # if isbigger == True:
            #     packtype = cls.PLAT_SUFFIX["default"]
            # else:
            packtype = cls.PLAT_SUFFIX[cls._plattype]
            PackSheet.execute(cls._sourcepath, cls._tarpath,
                              confkey, False, packtype)
        else:
            logging.info("Not find the texture!!")
            logging.info("Not find the texture!!")
            logging.error("Chk the key--->>%s is under the config file \n< %s >!\n\n chk it first!",
                          confkey, json.dumps(cls._texcfg, sort_keys=True, indent=4))
            sys.exit()

    @classmethod
    def _move_unimg(cls, fileobj):
        tag = str(time.time())
        tmpfile = fileobj + tag
        shutil.copyfile(fileobj, tmpfile)
        logging.info("Copy un-texture file-->>%s", fileobj)
        shutil.copyfile(fileobj, tmpfile)
        os.renames(tmpfile, tmpfile.replace(
            cls._respath, cls._tarpath).replace(tag, ""))

    @classmethod
    def _init_params(cls, confdic, isclean):
        # cls property
        try:
            cls._respath = os.path.join(cls._projpath, confdic["respath"])
            cls._tarpath = os.path.join(cls._projpath, confdic["tarpath"])
            cls._plattype = confdic["platform"]
            cls._isclean = isclean
            cls._retdbfile = os.path.join(cls._projpath, DB_FILENAME)
        except KeyError as kerr:
            logging.error("Chk the config first! %s", kerr)
            sys.exit()
        logging.info('===============================')
        logging.info("Config of release-res is ->%s",
                     json.dumps(confdic, sort_keys=True, indent=4))
        logging.info('===============================')

        # cfg property
        jsconf = os.path.join(cls._sourcepath, "resconf.data")
        jfile = open(jsconf, "r+")
        pcfg = json.loads(jfile.read().decode('utf-8'))
        jfile.close()
        cls._texcfg = pcfg

    @classmethod
    def _chk_baseres_all(cls):
        if cls._isclean is True:
            if os.path.isfile(cls._retdbfile):
                os.remove(cls._retdbfile)
            if os.path.isdir(cls._tarpath):
                shutil.rmtree(cls._tarpath)
        if os.path.isdir(cls._tarpath) is False:
            os.mkdir(cls._tarpath)
        ret = []
        # 创建表（如果不存在才创建）
        tbconf = [
            dict(filename="str"),
            dict(md5="str")
        ]
        LuaPackRes.sql_create_tb(cls._retdbfile, "RES_MD5", tbconf)

        # 文件夹忽略规则
        def _ignore_rule(fileobj):
            ig_dnames = []  # 忽略的文件夹名
            ig_fnames = []  # 忽略的文件名
            ig_suffix = [".plist", ".DS_Store"]  # 忽略文件格式

            fdir = fileobj.split(os.sep)[-2]
            fbname = fileobj.split(os.sep)[-1]
            for suffix in ig_suffix:
                if fbname.endswith(suffix) is True:
                    logging.debug("because the suffix-->>%s", fileobj)
                    return True
            for dname in ig_dnames:
                if fdir == dname:
                    logging.debug("because the dirname-->>%s", fileobj)
                    return True
            for fname in ig_fnames:
                if fname == fbname:
                    logging.debug("because the filename-->>%s", fileobj)
                    return True

            return False

        # 文件列表
        md5list = LuaPackRes.chk_resmd5(
            cls._respath, cls._projpath, _ignore_rule)

        cls._chglist = []
        # 存储整个文件列表
        for fname, md5 in md5list.items():
            keyname = fname.replace(os.sep, "_")
            (isexist, isdif) = cls._is_baseres_dif(md5, keyname)
            if (isexist is False) or (isdif is True):
                logging.debug(
                    "%s is diff or isexist||||isdif %s|||isexist %s", fname, isdif, isexist)
                ret.append(fname)
            datacont = dict(str_1=keyname, str_2=md5)

            cls._chglist.append(dict(fname=fname, datacont=datacont,
                                     isexist=isexist, isdif=isdif, keyname=keyname, md5=md5))
        return ret

    @classmethod
    def _is_baseres_dif(cls, oldmd5, keyname):
        # keyname
        isexist = None
        isdif = None
        ret = LuaPackRes.sql_get_data(
            cls._retdbfile, "RES_MD5", "filename='%s'" % keyname)
        retcnt = len(ret)
        isexist = retcnt > 0
        if (retcnt > 0):
            isdif = oldmd5 != ret[0][1]
        return (isexist, isdif)

    @classmethod
    def execute(cls, projpath, sourcepath, confdic, isclean=False):
        ''' 执行 '''
        # init config
        cls._projpath = projpath
        cls._sourcepath = sourcepath
        # init parms
        cls._init_params(confdic, isclean)
        # chk res md5
        chglist = cls._chk_baseres_all()
        logging.info("%s path have change file list-->>%s",
                     cls._respath, json.dumps(chglist, sort_keys=True, indent=4))
        # fmt diff list
        for filename in chglist:
            fileobj = cls._projpath + filename
            confkey = filename.split(os.sep)[-1].split(".")[0]
            if os.path.isfile(fileobj):
                if (filename.endswith(".png") or filename.endswith(".jpg")) and cls._texcfg.has_key(confkey):
                    cls._pack_img(fileobj, filename)
                else:
                    cls._move_unimg(fileobj)
        # copy and commit filelist

        # save sql
        logging.info("Save the res info to sqlite....")
        for chgobj in cls._chglist:
            isexist = chgobj["isexist"]
            isdif = chgobj["isdif"]
            datacont = chgobj["datacont"]
            keyname = chgobj["keyname"]
            md5 = chgobj["md5"]
            if (isexist is False):
                LuaPackRes.sql_save_res(cls._retdbfile, "RES_MD5", datacont)
            else:
                if (isdif is True):
                    LuaPackRes.sql_update_res(
                        cls._retdbfile, "RES_MD5", "md5='%s'" % md5, "filename='%s'" % keyname)


if __name__ == "__main__":
    print("======================================")
    print("=============ReleaseRes===============")
    print("======================================")

    basepath = os.path.dirname(__file__)
    binpath = os.path.join(basepath, "texture-tools")

    os.environ["texturetool"] = binpath

    DEBUG = False
    if DEBUG is True:
        projpath = "/data0/public_work/yuenan/client/trunk"
        sourpath = "/data0/public_work/yuenan/share/resource"
        dconf = dict(
            respath="res",
            tarpath="res_etc1",
            platform="android"
        )
        # dconf = dict(
        #     respath="res",
        #     tarpath="res_pvr",
        #     platform="ios"
        # )
        ReleaseRes.execute(projpath, sourpath, dconf, isclean=True)
        sys.exit()

    parser = OptionParser()
    # type 1:public apk by a jsonfile
    parser.add_option("-b", "--basepath", dest="projpath",
                      default=None, help="Input the tools path!")
    parser.add_option("-s", "--sourcepath", dest="sourcepath", default=None,
                      help="Input the json config file for pack the apk!")
    parser.add_option("-p", "--platform", dest="platf",
                      default=None, help="Project base path")
    parser.add_option("-n", "--isclean", dest="isclean", default=True,
                      help="Input if to clean the sqlite3")

    (opts, args) = parser.parse_args()
    if (opts.projpath and opts.sourcepath and opts.platf):
        pcfg = RELEASE_PLAT_CONFIG[opts.platf]
        ReleaseRes.execute(opts.projpath, opts.sourcepath, pcfg, opts.isclean)
